package org.swizframework
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.core.Application;
	import mx.events.FlexEvent;
	import mx.logging.ILogger;
	import mx.logging.Log;
	import mx.logging.LogEventLevel;
	
	//[DefaultProperty("beans")]
	public class SwizConfig extends EventDispatcher
	{
		private static const logger:ILogger = Log.getLogger("SwizConfig");
		
		private var _strict:Boolean = false;
		private var _mediateBubbledEvents:Boolean = false;
		private var _serviceCallFaultHandler:Function;
		private var _logEventLevel:int = LogEventLevel.WARN;
		private var _eventPackages:Array;
		private var _viewPackages:Array;
		private var _beanLoaders:Array;
		
		//public var beans:Array;
		
		/**
		 * 
		 * @param strict flag to enable runtime validation of mediated events
		 * 
		 */		
		public function set strict(strict:Boolean):void
		{
			_strict = strict;
		}
		
		/**
		 * 
		 * @param mediate flag to enable mediate bubbled events
		 * 
		 */		
		public function set mediateBubbledEvents( mediate:Boolean ):void
		{
			_mediateBubbledEvents = mediate;
		}
		
		public function set serviceCallFaultHandler( f:Function ):void
		{
			_serviceCallFaultHandler = f;
		}
		
		/**
		 * 
		 * @param logEventLevel for the swizframework internal logs (default is WARN)
		 * @see mx.logging.LogEventLevel
		 * 
		 */		
		public function set logEventLevel(logEventLevel:int):void
		{
			_logEventLevel = logEventLevel;
		}
		
		/**
		 * 
		 * @param eventPackages can be either a real array of strings or strings seperated with ","
		 * 
		 */		
		public function set eventPackages(eventPackages:*):void
		{
			if(eventPackages is Array)
			{
				_eventPackages = eventPackages as Array;
			}
			else if(eventPackages is String)
			{
				var s:String = eventPackages as String;
				s = s.replace(" ","");
				var a:Array = s.split(",");
				_eventPackages = a;
			}
			else
			{
				throw new Error("eventPackages set with unknown type. Supported types are Array or String.");
			}
		}
		
		/**
		 * 
		 * @param viewPackages can be either a real array of strings or strings seperated with ","
		 * 
		 */		
		public function set viewPackages(viewPackages:*):void
		{
			if(viewPackages is Array)
			{
				_viewPackages = viewPackages as Array;
			}
			else if(viewPackages is String)
			{
				var s:String = viewPackages as String;
				s = s.replace(" ","");
				var a:Array = s.split(",");
				_viewPackages = a;
			}
			else
			{
				throw new Error("viewPackages set with unknown type. Supported types are Array or String.");
			}
		}
		
		/**
		 * 
		 * @param a Array of BeanLoader
		 * @see org.swizframework.util.BeanLoader
		 * 
		 */		
		public function set beanLoaders(a:Array):void
		{
			_beanLoaders = a;
		}
		
		public function SwizConfig()
		{
			init();
		}
		
		private function init():void
		{
			// wait for preinitialize to init Swiz
			// before that systemManager is not available yet
			Application.application.addEventListener(FlexEvent.PREINITIALIZE, preInitHandler, false, 0, true);
		}
		
		private function preInitHandler(e:Event):void
		{
			Application.application.removeEventListener(FlexEvent.PREINITIALIZE, preInitHandler);
			
			var swizInstance:Swiz = Swiz.getInstance();
			
			swizInstance.setLogLevel(_logEventLevel);
			if(Swiz.hasLogLevel(LogEventLevel.INFO))
				logger.info("Init Swiz");
				
			swizInstance.setStrict(_strict);
			swizInstance.setMediateBubbledEvents(_mediateBubbledEvents);
			
			if(_serviceCallFaultHandler != null)
				swizInstance.setServiceCallFaultHandler(_serviceCallFaultHandler);
			
			if(_eventPackages != null)
			{
				for each(var eventPackage:String  in _eventPackages)
				{
					swizInstance.addEventPackage(eventPackage);
				}
			}

			if(_viewPackages != null)
			{
				for each(var viewPackage:String in _viewPackages)
				{
					swizInstance.addViewPackage(viewPackage);
				}
			}

			if(_beanLoaders != null)
				swizInstance.loadBeans(_beanLoaders);
			
		}

		
	}
}